﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Entities.PlatAdmin;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Wq.Core.Common.Helper;
using Wq.Core.Extensions;
using Wq.Core.Extensions.Assembly.AutoMapper;
using Wq.Core.Extensions.Assembly.Redis;
using Wq.Core.Extensions.Assembly.SqlSugar;
using Wq.Core.Extensions.ServiceExtensions.Framework;
using Wq.Core.Model;
using Wq.Core.PlatAdminService.Models;

namespace Wq.Core.PlatAdminService
{
    public class RoleService: BaseRepository<RoleInfo>, IRegister
    {


        private readonly BaseRepository redisRepository;
        public RoleService(BaseRepository redisRepository)
        {
            this.redisRepository = redisRepository;
        }

        #region 菜单
        /// <summary>
        /// 获取全部菜单
        /// </summary>
        /// <returns></returns>
        private List<Menu> PrivilegeFactory<TDescriptor>()
        {
            var type = typeof(TDescriptor);
            var fields = type.GetFields();

            List<Menu> list = new List<Menu>();
            foreach (var field in fields)
            {

                if (!field.FieldType.IsEnum)
                    continue;

                var Route = Convert.ToInt32(field.GetValue(null));
                var menus = field.GetCustomAttributes<MenuAttribute>(false);
                var permissions = field.GetCustomAttributes<PermissionAttribute>(false);

                List<Menu.Privilege> PrivilegeTypes = new List<Menu.Privilege>();
                foreach (var permission in permissions)
                    foreach (var Privilege in permission.Privileges)
                        PrivilegeTypes.Add(new Menu.Privilege { Id = (int)Privilege, Name = EnumHelper.ToDescription(Privilege) });

                foreach (var menu in menus)
                {

                    if (!string.IsNullOrEmpty(menu.FirstName))
                    {
                        if (list.Where(p => p.Name == menu.FirstName).Count() == 0)
                        {
                            var newMenu = new Menu
                            {
                                Route = Route,
                                Name = menu.FirstName,
                                Path = menu.Path,
                                Icon = menu.Icon,
                                Children = new List<Menu>() { }
                            };
                            list.Add(newMenu);
                            if (menu.Permission) newMenu.Permissions = PrivilegeTypes;
                        }
                        if (!string.IsNullOrEmpty(menu.SecondName))
                        {
                            var secondList = list.Where(p => p.Name == menu.FirstName).FirstOrDefault();
                            if (secondList.Children.Where(p => p.Name == menu.SecondName).Count() == 0)
                            {
                                var newMenu = new Menu
                                {
                                    Route = Route,
                                    Name = menu.SecondName,
                                    Path = menu.Path,
                                    Icon = menu.Icon,
                                    Children = new List<Menu>() { }
                                };
                                secondList.Children.Add(newMenu);

                                if (menu.Permission) newMenu.Permissions = PrivilegeTypes;
                            }
                        }
                        if (!string.IsNullOrEmpty(menu.ThirdName))
                        {
                            var SecondList = list.Where(p => p.Name == menu.FirstName).FirstOrDefault();
                            var thirdList = SecondList.Children.Where(p => p.Name == menu.SecondName).FirstOrDefault();
                            if (thirdList.Children.Where(p => p.Name == menu.ThirdName).Count() == 0)
                            {
                                var newMenu = new Menu
                                {
                                    Route = Route,
                                    Name = menu.ThirdName,
                                    Path = menu.Path,
                                    Icon = menu.Icon,
                                    Children = new List<Menu>() { }
                                };

                                thirdList.Children.Add(newMenu);
                                if (menu.Permission) newMenu.Permissions = PrivilegeTypes;
                            }
                        }
                    }

                }
            }

            foreach (var menu in list)
            {
                if (menu.Children != null && menu.Children.Count() == 0)
                {
                    menu.Children = null;
                }
                else
                {
                    foreach (var secondMenu in menu.Children)
                    {
                        if (secondMenu.Children != null && secondMenu.Children.Count() == 0)
                        {
                            secondMenu.Children = null;
                        }
                        else
                        {
                            foreach (var thirdMenu in secondMenu.Children)
                            {
                                if (thirdMenu.Children != null && thirdMenu.Children.Count() == 0)
                                {
                                    thirdMenu.Children = null;
                                }
                            }
                        }
                    }
                }
            }
            return list;
        }

        /// <summary>
        /// 获取全部菜单
        /// </summary>
        /// <returns></returns>
        public List<Menu> GetPrivilege()
        {
            return redisRepository.Get(CacheKey.Menu, PrivilegeFactory<PrivilegeDescriptor>()).Result;
        }
        #endregion




        /// <summary>
        /// 添加权限组
        /// </summary>
        /// <param name="role"></param>
        public void Create(RoleEditor role)
        {
            
            var result = Context.Ado.UseTran(() =>
            {
                var info = role.Map<RoleInfo>();
                info.Id = Context.Insertable(info).ExecuteReturnIdentity();
                if (info.Id > 0)
                {
                    var list = role.Privileges.Map<RolePrivilegeInfo>();
                    list.ForEach(item => {
                        item.RoleId = info.Id;
                    });
                    Context.Insertable(list).ExecuteCommand();
                }

            });

            if (!result.IsSuccess)
            {
                throw new MyException("添加失败");
            }
        }
        /// <summary>
        /// 修改权限组
        /// </summary>
        /// <param name="role"></param>
        public void Save(RoleEditor role)
        {
            var result = Context.Ado.UseTran(() =>
            {
                var info = role.Map<RoleInfo>();
                Context.Updateable(info).ExecuteCommand();
                var rolePrivileges = role.Privileges.Select(p => p.Id);
                Context.Deleteable<RolePrivilegeInfo>().Where(p => !rolePrivileges.Contains(p.Id)).ExecuteCommand();
                var list = role.Privileges.Map<RolePrivilegeInfo>();
                Context.Updateable(list.Where(p => p.Id > 0).ToList()).ExecuteCommand();
                var addlist = list.Where(p => p.Id == 0).ToList();
                addlist.ForEach(item => {
                    item.RoleId = info.Id;
                });
                Context.Insertable(addlist).ExecuteCommand();
              

            });

            if (!result.IsSuccess)
            {
                throw new MyException("修改失败");
            }
        }

       
        /// <summary>
        /// 获取权限组详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<PrivilegeView> PrivilegesByRoleId(long id)
        {
            return Context.Queryable<RolePrivilegeInfo>().Where(r => r.RoleId == id).Select<PrivilegeView>().ToList();
        }

        /// <summary>
        /// 获取权限组详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public RoleEditor Details(long id)
        {
           return Context.Queryable<RoleInfo>().Select<RoleEditor>().Mapper(p => {
               p.Privileges = Context.Queryable<RolePrivilegeInfo>().Where(r => r.RoleId == p.Id).Select<RoleEditor.RolePrivilege>().ToList();
           }).First(p => p.Id == id);
        }

        public void Delete(long id)
        {
         
          
            var result = Context.Ado.UseTran(() =>
            {
                Context.Deleteable<RoleInfo>().Where(p => p.Id == id).ExecuteCommand();
                Context.Deleteable<RolePrivilegeInfo>().Where(p => p.RoleId == id).ExecuteCommand();

            });

            if (!result.IsSuccess)
            {
                throw new MyException("删除失败");
            }
        }

    }
}
